package com.hzy.generator.service.impl;

import com.google.common.collect.Lists;
import com.hzy.generator.entity.DomainBo;
import com.hzy.generator.entity.FieldVo;
import com.hzy.generator.entity.MongoManagementParameter;
import com.hzy.generator.entity.MongoRouterParameter;
import com.hzy.generator.service.GeneratorMongoService;
import com.hzy.generator.utils.FreeMarkerUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ResourceUtils;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class GeneratorMongoServiceImpl implements GeneratorMongoService {
    private static List<DomainBo> domainBos = new ArrayList<>();

    @Autowired
    private MongoManagementParameter mongoManagementParameter;
    @Autowired
    private MongoRouterParameter mongoRouterParameter;

    @Override
    public void initTableInfo(String entityFileNames) {
        String entityPath = mongoManagementParameter.getBasePath()
                        .concat("/").concat(mongoManagementParameter.getEntityModule())
                        .concat("/").concat(mongoManagementParameter.getEntityPath());

        File base = new File(entityPath);
        if(!base.exists()){
            return;
        }
        List<File> entityList = new ArrayList<>();
        if(base.isDirectory() && base.listFiles().length < 1){
            return;
        }
        if(base.isDirectory()){
            entityList.addAll(Arrays.asList(base.listFiles()));
        }else {
            entityList.add(base);
        }

        entityList.stream().peek(file -> {
            List<String> columnList = new ArrayList<>();
            try {
                String fileName = FilenameUtils.getBaseName(file.getName());
                if(!StringUtils.contains(entityFileNames, fileName)){
                    return;
                }
                DomainBo domainBo = new DomainBo();

                getColumnByPath(file, domainBo, columnList);
                //默认作者
                if(StringUtils.isBlank(domainBo.getAuthor())){
                    domainBo.setAuthor("请替换作者");
                }
                //默认介绍
                if(StringUtils.isBlank(domainBo.getComment())){
                    domainBo.setComment("请替换" + fileName + "介绍");
                }
                domainBos.add(domainBo);

                //entity中添加默认字段
                addDefaultColumn(columnList, file);
            } catch (Exception e){
                e.printStackTrace();
            }
        }).collect(Collectors.toList());
    }

    public void getColumnByPath(File file, DomainBo domainBo, List<String> columnList) throws Exception{
        List<String> fileLine = FileUtils.readLines(file);

        for (int i = 0; i < fileLine.size(); i++) {
            String field = fileLine.get(i);
            if(StringUtils.isEmpty(field)){
                continue;
            }
            //实体类描述
            if(StringUtils.contains(field, "desc") && StringUtils.contains(field, "*")){
                domainBo.setComment(field.replace("*", "")
                        .replace("desc", "").replace("@", "")
                        .replace(":", "").replace("：", "").trim());
                continue;
            }
            //作者
            if(StringUtils.contains(field, "author") && StringUtils.contains(field, "*")){
                domainBo.setAuthor(field.replace("*", "")
                        .replace("author", "").replace("@", "")
                        .replace(":", "").replace("：", "").trim());
                continue;
            }
            if(StringUtils.containsAny(field, "//", "serialVersionUID", "import",
                    "package", "*", "}")){
                continue;
            }
            if(StringUtils.contains(field, "@Id")){
                addKeys(domainBo, fileLine.get(++i));
                continue;
            }
            if(StringUtils.contains(field, "Transient")){
                continue;
            }
            if(StringUtils.contains(field, "@")){
                continue;
            }
            if(StringUtils.contains(field, "Serializable")){
                if(field.indexOf(" extends ") != -1){
                    String exName = field.substring(field.indexOf("extends") + "extends".length()).trim();
                    String parentPath = file.getParentFile().getPath() + "/" + exName.split(" ")[0] + ".java";

                    getColumnByPath(new File(parentPath), domainBo, columnList);
                }
                addClassName(domainBo, field);
                continue;
            }
            if(!StringUtils.containsAny(field, "private", "protected", "public") ||
                    !StringUtils.containsAny(field, ";")){
                continue;
            }
            columnList.add(addColumn(domainBo, field));
        }
    }

    private void addDefaultColumn(List<String> columnList, File file) throws Exception {
        if(CollectionUtils.containsAny(columnList, Arrays.asList("ids"))
            && CollectionUtils.containsAny(columnList, Arrays.asList("createTime"))
            && CollectionUtils.containsAny(columnList, Arrays.asList("updateTime"))){
            return;
        }

        List<String> fileLine = FileUtils.readLines(file);
        Integer index = Collections.binarySearch(fileLine, "}");
        if(!columnList.contains("createTime")){
            if(!StringUtils.isBlank(fileLine.get(index - 1))){
                fileLine.add(index, "    //创建时间");
            }else{
                index = index -1;
            }
            fileLine.add(index + 1, "    private Long createTime;");

            if(!CollectionUtils.containsAny(fileLine, Arrays.asList("import org.springframework.data.mongodb.core.index.Indexed;"))){
                fileLine.add(2, "import org.springframework.data.mongodb.core.index.Indexed;");
            }
        }
        index = Collections.binarySearch(fileLine, "}");
        if(!columnList.contains("updateTime")){
            if(!StringUtils.isBlank(fileLine.get(index - 1))){
                fileLine.add(index, "    //修改时间");
            }else{
                index = index -1;
            }
            fileLine.add(index + 1, "    private Long updateTime;");

            if(!CollectionUtils.containsAny(fileLine, Arrays.asList("import org.springframework.data.mongodb.core.index.Indexed;"))){
                fileLine.add(2, "import org.springframework.data.mongodb.core.index.Indexed;");
            }
        }
        //ids
        addTransientColumn("String", "ids", "批量操作主键id集合", fileLine, columnList);
        //keyword,searchStartTime,searchEndTime
        addTransientColumn("String", "keyword", "搜索关键字", fileLine, columnList);
        addTransientColumn("Long", "searchStartTime", "搜索开始时间", fileLine, columnList);
        addTransientColumn("Long", "searchEndTime", "搜索结束时间", fileLine, columnList);

        FileUtils.writeLines(file, fileLine);
    }

    public void addTransientColumn(String columnType, String column, String desc, List<String> fileLine, List<String> columnList){
        if(!columnList.contains(column)){
            List<String> line = Lists.newArrayList();
            line.add("");
            line.add("    /**");
            line.add("     * " + desc);
            line.add("     **/");
            line.add("    @Transient");
            line.add("    private " + columnType + " " + column + ";");

            Integer index = Collections.binarySearch(fileLine, "}");
            if(!StringUtils.isBlank(fileLine.get(index - 1))){
                fileLine.addAll(index, line);
            }else{
                fileLine.addAll(index - 1, line);
            }

            if(!CollectionUtils.containsAny(fileLine,
                    Arrays.asList("import org.springframework.data.annotation.Transient;"))){
                fileLine.add(2, "import org.springframework.data.annotation.Transient;");
            }
        }
    }

    private String addColumn(DomainBo domainBo, String field) {
        List<FieldVo> columns = domainBo.getColumns();
        if(null == columns){
            columns = new ArrayList<>();
        }
        field = field.trim();

        field = field.trim().replace(";", "")
                .replace("private", "")
                .replace("protected", "").trim();
        FieldVo fieldVo = new FieldVo();
        String[] ary = field.split(" ");
        fieldVo.setType(ary[0]);
        fieldVo.setName(ary[1]);
        fieldVo.setColName(ary[1]);
        fieldVo.setExtra("-1");
        columns.add(fieldVo);
        domainBo.setColumns(columns);
        if(ary.length > 2){
            return ary[2];
        }
        return ary[1];
    }

    private void addKeys(DomainBo domainBo, String field) {
        List<FieldVo> keys = domainBo.getKeys();
        if(null == keys){
            keys = new ArrayList<>();
        }

        field = field.trim().replace(";", "")
                .replace("private", "")
                .replace("protected", "").trim();
        FieldVo fieldVo = new FieldVo();
        String[] ary = field.split(" ");
        if(ary.length > 2){
            fieldVo.setType(ary[1]);
            fieldVo.setName(ary[2]);
            fieldVo.setColName(ary[2]);
        }else if(ary.length == 2){
            fieldVo.setType(ary[0]);
            fieldVo.setName(ary[1]);
            fieldVo.setColName(ary[1]);
        }
        fieldVo.setExtra("-1");
        keys.add(fieldVo);

        domainBo.setKeys(keys);
    }

    private String addClassName(DomainBo domainBo, String field) {
        String result = field.replace("public", "")
                .replace("class", "")
                .replace("implements", "")
                .replace("Serializable", "")
                .replace("{", "").trim();
        if(StringUtils.contains(result, " ")){
            result = result.split(" ")[0];
        }
        domainBo.setClassName(result);
        return result;
    }

    @Override
    public void startRouterCreate(String entityFileNames) throws Exception {
        if(StringUtils.isBlank(entityFileNames)){
            return;
        }
        //初始化
        if(domainBos.size() < 1){
            initTableInfo(entityFileNames);
        }

        for (DomainBo temp : domainBos) {
            temp.setDatetime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

            buildRouterController(temp, "mg_router_controller.ftl");

            buildRouterService(temp, "mg_router_service.ftl");
            buildRouterServiceImpl(temp, "mg_router_serviceImpl.ftl");

            buildRouterClient(temp, "mg_router_client.ftl");
        }
    }

    public void buildRouterClient(DomainBo domain, String templateName) {
        try {
            Configuration cfg = FreeMarkerUtils.getConfiguration();
            cfg.setDirectoryForTemplateLoading(getTemplateDir());
            /* 在整个应用的生命周期中，这个工作你可以执行多次 */
            /* 获取或创建模板*/
            Template temp = cfg.getTemplate(templateName, "UTF-8");

            String path = mongoRouterParameter.getBasePath()
                    .concat("/").concat(mongoRouterParameter.getServiceModule())
                    .concat("/").concat(mongoRouterParameter.getClientPath());

            File pathFile = new File(path);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }

            File file = new File(path + "/" + domain.getClassName() + "ServiceClient.java");
            if(file.exists()){
                return;
            }
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

            /* 将模板和数据模型合并 */
            Map<String, Object> params = new HashMap<String, Object>(1);
            params.put("clientPackageName", mongoRouterParameter.getBaseClassPath() + ".client");
            params.put("apiPackageName", mongoManagementParameter.getBaseClassPath() + ".api");
            params.put("backPackageName", mongoRouterParameter.getBaseClassPath() + ".client.fallback");
            params.put("domain", domain);
            temp.process(params, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void buildRouterBack(DomainBo domain, String templateName) {
        try {
            Configuration cfg = FreeMarkerUtils.getConfiguration();
            cfg.setDirectoryForTemplateLoading(getTemplateDir());
            /* 在整个应用的生命周期中，这个工作你可以执行多次 */
            /* 获取或创建模板*/
            Template temp = cfg.getTemplate(templateName, "UTF-8");

            String path = mongoRouterParameter.getBasePath()
                    .concat("/").concat(mongoRouterParameter.getServiceModule())
                    .concat("/").concat(mongoRouterParameter.getFallbackPath());

            File pathFile = new File(path);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }

            File file = new File(path + "/" + domain.getClassName() + "ServiceFallback.java");
            if(file.exists()){
                return;
            }
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

            /* 将模板和数据模型合并 */
            Map<String, Object> params = new HashMap<String, Object>(1);
            params.put("backPackageName", mongoRouterParameter.getBaseClassPath() + ".client.fallback");
            params.put("apiPackageName", mongoRouterParameter.getBaseClassPath() + ".api");
            params.put("clientPackageName", mongoRouterParameter.getBaseClassPath() + ".client");
            params.put("domain", domain);
            temp.process(params, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void buildRouterService(DomainBo domain, String templateName) {
        try {
            Configuration cfg = FreeMarkerUtils.getConfiguration();
            cfg.setDirectoryForTemplateLoading(getTemplateDir());
            /* 在整个应用的生命周期中，这个工作你可以执行多次 */
            /* 获取或创建模板*/
            Template temp = cfg.getTemplate(templateName, "UTF-8");

            String path = mongoRouterParameter.getBasePath()
                    .concat("/").concat(mongoRouterParameter.getServiceModule())
                    .concat("/").concat(mongoRouterParameter.getServicePath());

            File pathFile = new File(path);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }

            File file = new File(path + "/" + domain.getClassName() + "Service.java");
            if(file.exists()){
                return;
            }
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

            /* 将模板和数据模型合并 */
            Map<String, Object> params = new HashMap<String, Object>(1);
            params.put("servicePackageName", mongoRouterParameter.getBaseClassPath() + ".service");
            params.put("domianPackageName", mongoManagementParameter.getBaseClassPath() + ".entity");
            params.put("domain", domain);
            temp.process(params, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void buildRouterServiceImpl(DomainBo domain, String templateName) {
        try {
            Configuration cfg = FreeMarkerUtils.getConfiguration();
            cfg.setDirectoryForTemplateLoading(getTemplateDir());
            /* 在整个应用的生命周期中，这个工作你可以执行多次 */
            /* 获取或创建模板*/
            Template temp = cfg.getTemplate(templateName, "UTF-8");

            String path = mongoRouterParameter.getBasePath()
                    .concat("/").concat(mongoRouterParameter.getServiceModule())
                    .concat("/").concat(mongoRouterParameter.getServiceImplPath());

            File pathFile = new File(path);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }

            File file = new File(path + "/" + domain.getClassName() + "ServiceImpl.java");
            if(file.exists()){
                return;
            }

            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

            /* 将模板和数据模型合并 */
            //Writer out = new OutputStreamWriter(System.out);
            Map<String, Object> params = new HashMap<String, Object>(1);
            params.put("serviceImplPackageName", mongoRouterParameter.getBaseClassPath() + ".service.impl");
            params.put("domianPackageName", mongoManagementParameter.getBaseClassPath() + ".entity");
            params.put("clientPackageName", mongoRouterParameter.getBaseClassPath() + ".client");
            params.put("servicePackageName", mongoRouterParameter.getBaseClassPath() + ".service");
            params.put("domain", domain);
            temp.process(params, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void buildRouterController(DomainBo domain, String templateName) {
        try {
            Configuration cfg = FreeMarkerUtils.getConfiguration();
            cfg.setDirectoryForTemplateLoading(getTemplateDir());
            /* 在整个应用的生命周期中，这个工作你可以执行多次 */
            /* 获取或创建模板*/
            Template temp = cfg.getTemplate(templateName, "UTF-8");

            String path = mongoRouterParameter.getBasePath()
                    .concat("/").concat(mongoRouterParameter.getDispatcherModule())
                    .concat("/").concat(mongoRouterParameter.getDispatcherPath());

            File pathFile = new File(path);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }

            File file = new File(path + "/" + domain.getClassName() + "Controller.java");
            if(file.exists()){
                return;
            }
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

            /* 将模板和数据模型合并 */
            //Writer out = new OutputStreamWriter(System.out);
            Map<String, Object> params = new HashMap<String, Object>(1);
            params.put("controllerPackageName", "com.hxkj.back.controller.lts");
            params.put("servicePackageName", mongoRouterParameter.getBaseClassPath() + ".service");
            params.put("domianPackageName", mongoManagementParameter.getBaseClassPath() + ".entity");
            params.put("domain", domain);
            temp.process(params, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void startManagementCreate(String entityFileNames) throws Exception {
        if(StringUtils.isBlank(entityFileNames)){
            return;
        }
        //初始化
        if(domainBos.size() < 1){
            initTableInfo(entityFileNames);
        }

        for (DomainBo temp : domainBos) {
            temp.setDatetime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));

            buildManagementDao(temp,"mg_management_dao.ftl");

            buildManagementDaoImpl(temp,"mg_management_daoImpl.ftl");

            buildManagementRemoteController(temp, "mg_management_remote_controller.ftl");

            buildManagementFrontController(temp, "mg_management_front_controller.ftl");

            buildManagementService(temp, "mg_management_service.ftl");

            buildManagementServiceImpl(temp, "mg_management_serviceImpl.ftl");

            buildManagementApi(temp, "mg_management_api.ftl");
        }
    }

    @Override
    public void buildManagementDao(DomainBo domain, String templateName) {
        try {
            Configuration cfg = FreeMarkerUtils.getConfiguration();
            cfg.setDirectoryForTemplateLoading(getTemplateDir());
            /* 在整个应用的生命周期中，这个工作你可以执行多次 */
            /* 获取或创建模板*/
            Template temp = cfg.getTemplate(templateName, "UTF-8");

            String path = mongoManagementParameter.getBasePath()
                    .concat("/").concat(mongoManagementParameter.getServiceModule())
                    .concat("/").concat(mongoManagementParameter.getDaoPath());

            System.out.println("path===" + path);

            File pathFile = new File(path);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }

            File file = new File(path + "/" + domain.getClassName() + "Dao.java");
            if(file.exists()){
                return;
            }
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

            /* 将模板和数据模型合并 */
            Map<String, Object> params = new HashMap<String, Object>(1);
            params.put("daoPackageName", mongoManagementParameter.getBaseClassPath() + ".dao");
            params.put("domianPackageName", mongoManagementParameter.getBaseClassPath() + ".entity");
            params.put("domain", domain);
            temp.process(params, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void buildManagementDaoImpl(DomainBo domain, String templateName) {
        try {
            Configuration cfg = FreeMarkerUtils.getConfiguration();
            cfg.setDirectoryForTemplateLoading(getTemplateDir());
            /* 在整个应用的生命周期中，这个工作你可以执行多次 */
            /* 获取或创建模板*/
            Template temp = cfg.getTemplate(templateName, "UTF-8");

            String path = mongoManagementParameter.getBasePath()
                    .concat("/").concat(mongoManagementParameter.getServiceModule())
                    .concat("/").concat(mongoManagementParameter.getDaoImplPath());

            System.out.println("path===" + path);

            File pathFile = new File(path);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }

            File file = new File(path + "/" + domain.getClassName() + "DaoImpl.java");
            if(file.exists()){
                return;
            }
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

            /* 将模板和数据模型合并 */
            //Writer out = new OutputStreamWriter(System.out);
            Map<String, Object> params = new HashMap<String, Object>(1);
            params.put("domianPackageName", mongoManagementParameter.getBaseClassPath() + ".entity");
            params.put("daoPackageName", mongoManagementParameter.getBaseClassPath() + ".dao");
            params.put("daoImplPackageName", mongoManagementParameter.getBaseClassPath() + ".dao.impl");
            params.put("domain", domain);
            temp.process(params, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void buildManagementService(DomainBo domain, String templateName) {
        try {
            Configuration cfg = FreeMarkerUtils.getConfiguration();
            cfg.setDirectoryForTemplateLoading(getTemplateDir());
            /* 在整个应用的生命周期中，这个工作你可以执行多次 */
            /* 获取或创建模板*/
            Template temp = cfg.getTemplate(templateName, "UTF-8");

            String path = mongoManagementParameter.getBasePath()
                    .concat("/").concat(mongoManagementParameter.getServiceModule())
                    .concat("/").concat(mongoManagementParameter.getServicePath());

            System.out.println("path===" + path);

            File pathFile = new File(path);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }

            File file = new File(path + "/" + domain.getClassName() + "Service.java");
            if(file.exists()){
                return;
            }
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

            /* 将模板和数据模型合并 */
            //Writer out = new OutputStreamWriter(System.out);
            Map<String, Object> params = new HashMap<String, Object>(1);
            params.put("servicePackageName", mongoManagementParameter.getBaseClassPath() + ".service");
            params.put("domianPackageName", mongoManagementParameter.getBaseClassPath() + ".entity");
            params.put("domain", domain);
            temp.process(params, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void buildManagementServiceImpl(DomainBo domain, String templateName) {
        try {
            Configuration cfg = FreeMarkerUtils.getConfiguration();
            cfg.setDirectoryForTemplateLoading(getTemplateDir());
            /* 在整个应用的生命周期中，这个工作你可以执行多次 */
            /* 获取或创建模板*/
            Template temp = cfg.getTemplate(templateName, "UTF-8");

            String path = mongoManagementParameter.getBasePath()
                    .concat("/").concat(mongoManagementParameter.getServiceModule())
                    .concat("/").concat(mongoManagementParameter.getServiceImplPath());

            System.out.println("path===" + path);

            File pathFile = new File(path);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }

            File file = new File(path + "/" + domain.getClassName() + "ServiceImpl.java");
            if(file.exists()){
                return;
            }
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

            /* 将模板和数据模型合并 */
            //Writer out = new OutputStreamWriter(System.out);
            Map<String, Object> params = new HashMap<String, Object>(1);
            params.put("daoPackageName", mongoManagementParameter.getBaseClassPath() + ".dao");
            params.put("domianPackageName", mongoManagementParameter.getBaseClassPath() + ".entity");
            params.put("servicePackageName", mongoManagementParameter.getBaseClassPath() + ".service");
            params.put("serviceImplPackageName", mongoManagementParameter.getBaseClassPath() + ".service.impl");
            params.put("domain", domain);
            temp.process(params, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void buildManagementRemoteController(DomainBo domain, String templateName) {
        try {
            Configuration cfg = FreeMarkerUtils.getConfiguration();
            cfg.setDirectoryForTemplateLoading(getTemplateDir());
            /* 在整个应用的生命周期中，这个工作你可以执行多次 */
            /* 获取或创建模板*/
            Template temp = cfg.getTemplate(templateName, "UTF-8");

            String path = mongoManagementParameter.getBasePath()
                    .concat("/").concat(mongoManagementParameter.getDispatcherModule())
                    .concat("/").concat(mongoManagementParameter.getDispatcherPath())
                    .concat("/").concat("remote");

            System.out.println("path===" + path);

            File pathFile = new File(path);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }

            File file = new File(path + "/" + domain.getClassName() + "ApiImpl.java");
            if(file.exists()){
                return;
            }
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

            /* 将模板和数据模型合并 */
            //Writer out = new OutputStreamWriter(System.out);
            Map<String, Object> params = new HashMap<String, Object>(1);
            params.put("apiPackageName", mongoManagementParameter.getBaseClassPath() + ".api");
            params.put("controllerPackageName", mongoManagementParameter.getBaseClassPath() + ".controller.remote");
            params.put("servicePackageName", mongoManagementParameter.getBaseClassPath() + ".service");
            params.put("domianPackageName", mongoManagementParameter.getBaseClassPath() + ".entity");
            params.put("domain", domain);
            temp.process(params, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void buildManagementFrontController(DomainBo domain, String templateName) {
        try {
            Configuration cfg = FreeMarkerUtils.getConfiguration();
            cfg.setDirectoryForTemplateLoading(getTemplateDir());
            /* 在整个应用的生命周期中，这个工作你可以执行多次 */
            /* 获取或创建模板*/
            Template temp = cfg.getTemplate(templateName, "UTF-8");

            String path = mongoManagementParameter.getBasePath()
                    .concat("/").concat(mongoManagementParameter.getDispatcherModule())
                    .concat("/").concat(mongoManagementParameter.getDispatcherPath())
                    .concat("/").concat("front");

            File pathFile = new File(path);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }

            File file = new File(path + "/" + domain.getClassName() + "Controller.java");
            if(file.exists()){
                return;
            }
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

            /* 将模板和数据模型合并 */
            //Writer out = new OutputStreamWriter(System.out);
            Map<String, Object> params = new HashMap<String, Object>(1);
            params.put("controllerPackageName", mongoManagementParameter.getBaseClassPath() + ".controller.front");
            params.put("servicePackageName", mongoManagementParameter.getBaseClassPath() + ".service");
            params.put("domianPackageName", mongoManagementParameter.getBaseClassPath() + ".entity");
            params.put("domain", domain);
            temp.process(params, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void buildManagementApi(DomainBo domain, String templateName) {
        try {
            Configuration cfg = FreeMarkerUtils.getConfiguration();
            cfg.setDirectoryForTemplateLoading(getTemplateDir());
            /* 在整个应用的生命周期中，这个工作你可以执行多次 */
            /* 获取或创建模板*/
            Template temp = cfg.getTemplate(templateName, "UTF-8");

            String path = mongoManagementParameter.getBasePath()
                    .concat("/").concat(mongoManagementParameter.getApiModle())
                    .concat("/").concat(mongoManagementParameter.getApiPath());

            System.out.println("path===" + path);

            File pathFile = new File(path);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }

            File file = new File(path + "/" + domain.getClassName() + "Api.java");
            if(file.exists()){
                return;
            }
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

            /* 将模板和数据模型合并 */
            //Writer out = new OutputStreamWriter(System.out);
            Map<String, Object> params = new HashMap<String, Object>(1);
            params.put("apiPackageName", mongoManagementParameter.getBaseClassPath() + ".api");
            params.put("domianPackageName", mongoManagementParameter.getBaseClassPath() + ".entity");
            params.put("domain", domain);
            temp.process(params, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void buildManagementBack(DomainBo domain, String templateName) {
        try {
            Configuration cfg = FreeMarkerUtils.getConfiguration();
            cfg.setDirectoryForTemplateLoading(getTemplateDir());
            /* 在整个应用的生命周期中，这个工作你可以执行多次 */
            /* 获取或创建模板*/
            Template temp = cfg.getTemplate(templateName, "UTF-8");

            String path = mongoManagementParameter.getBasePath()
                    .concat("/").concat(mongoManagementParameter.getApiModle())
                    .concat("/").concat(mongoManagementParameter.getApiPath());

            System.out.println("path===" + path);

            File pathFile = new File(path);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }

            File file = new File(path + "/" + domain.getClassName() + "ApiFallback.java");
            if(file.exists()){
                return;
            }

            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));

            /* 将模板和数据模型合并 */
            //Writer out = new OutputStreamWriter(System.out);
            Map<String, Object> params = new HashMap<String, Object>(1);
            params.put("apiPackageName", mongoManagementParameter.getBaseClassPath() + ".api");
            params.put("domianPackageName", mongoManagementParameter.getBaseClassPath() + ".entity");
            params.put("domain", domain);
            temp.process(params, out);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private File getTemplateDir() throws Exception {
        return ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "ftl");
    }
}
